package com.ansion.utils.permission;

import static android.os.Build.VERSION_CODES.M;

import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;


import com.ansion.basetool.R;
import com.ansion.utils.PermissionUtils;
import com.ansion.utils.ResourceUtils;
import com.ansion.utils.ThemeActivity;

import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;


@TargetApi(M)
public final class PermissionShadowActivity extends ThemeActivity {
    private static final String ARG_PERMISSIONS = "permissions";
    private static final String ARG_REQUEST_DESC = "permission_request";
    private static final String ARG_GUIDE_DESC = "permission_guide";
    private static final String ARG_FORCE_DIALOG = "permission_force_dialog";
    private static final String ARG_FORCE_NO_DIALOG = "permission_force_no_dialog";
    private static final String ARG_PRIME_STYLE = "permission_prime_style";
    private static final String SAVE_RATIONALE = "save-rationale";
    private static final int REQUEST_CODE = 42;
    private static final int REQUEST_CODE_CHECK_SETTING = 43;

    static void start(final Context context, String request, String guide, boolean forceDialog,final String[] permissions, boolean primeStyle,boolean forceNoDialog) {

        if (permissions==null || permissions.length ==0) return;

        final Intent intent = new Intent(context, PermissionShadowActivity.class)
                .putExtra(ARG_PERMISSIONS, permissions)
                .putExtra(ARG_REQUEST_DESC,request)
                .putExtra(ARG_GUIDE_DESC,guide)
                .putExtra(ARG_FORCE_DIALOG,forceDialog)
                .putExtra(ARG_FORCE_NO_DIALOG,forceNoDialog)
                .putExtra(ARG_PRIME_STYLE, primeStyle);
        if(!(context instanceof Activity)) {
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        context.startActivity(intent);
    }

    private boolean[] shouldShowRequestPermissionRationale;

    private String[] permissions;


    private String request="";
    private String guide="";
    private boolean forceDialog = false;
    private boolean forceNoDialog = false;

    private boolean showGuide = true; // 所有权限都并用户设置为不再提醒
    private boolean first = true;
    private boolean primeStyle = false;
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setWindowFlag();

        RealRxPermission.shadowActivityWeakReference = new WeakReference<>(this);

        handleIntent(getIntent());

        if (savedInstanceState != null) {
            shouldShowRequestPermissionRationale = savedInstanceState.getBooleanArray(SAVE_RATIONALE);
        }

        if (permissions==null || permissions.length==0){
            finish();
        } else {

            for (String permission : permissions) {
                if (!PermissionSharedPref.getInstance(this).isFirstRequest(permission)) {
                    first = false;
                }
            }

            showGuide = isDeniedForever(permissions);

            if (first && !forceDialog) {
                startRequestPermissions();
            } else {
                if (!showGuide) {
                    // --> continue
                    if (forceNoDialog) {
                        startRequestPermissions();
                    } else {
                        PreRequestDialog preRequestDialog = PreRequestDialog.newInstance(getPermissionIcon(permissions), request, primeStyle);
                        showDialogFragment(preRequestDialog);
                    }
                } else {
                    // --> settings
                    if (forceNoDialog) {
                        try {
                            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
//                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            Uri uri = Uri.fromParts("package", getPackageName(), null);
                            intent.setData(uri);
                            startActivityForResult(intent, 43);
                        } catch (Throwable th) {
                            th.printStackTrace();
                        }
                    } else {
                        NoPermissionDialog noPermissionDialog = NoPermissionDialog.newInstance(getPermissionIcon(permissions), guide, primeStyle);
                        showDialogFragment(noPermissionDialog);
                    }
                }
            }
        }
    }

    @SuppressLint("MissingSuperCall")
    @Override
    protected void onNewIntent(final Intent intent) {
        handleIntent(intent);
    }

    private void handleIntent(final Intent intent) {
        if (intent == null) return;
        permissions = intent.getStringArrayExtra(ARG_PERMISSIONS);
        shouldShowRequestPermissionRationale = rationales(permissions);
        request = intent.getStringExtra(ARG_REQUEST_DESC);
        guide = intent.getStringExtra(ARG_GUIDE_DESC);
        forceDialog = intent.getBooleanExtra(ARG_FORCE_DIALOG, false);
        forceNoDialog = intent.getBooleanExtra(ARG_FORCE_NO_DIALOG, false);
        primeStyle = intent.getBooleanExtra(ARG_PRIME_STYLE, false);
        // requestPermissions(permissions, REQUEST_CODE);
    }

    @SuppressLint("MissingSuperCall")
    @Override
    public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) {
        if (requestCode == REQUEST_CODE) {
            final boolean[] rationales = rationales(permissions);
            finish();

            RealRxPermission.getInstance(getApplication()).onRequestPermissionsResult(grantResults, shouldShowRequestPermissionRationale, rationales, permissions);
        }
    }

    private boolean isNotAskPermission(String permission) {
        return !PermissionSharedPref.getInstance(this).isFirstRequest(permission) && !shouldShowRequestPermissionRationale(permission);
    }

    private boolean isDeniedForever(String... permissions) {
        for (String permission : permissions) {
            if (!PermissionUtils.hasPermission(ResourceUtils.getContext(), permission) && isNotAskPermission(permission)) {
                return true;
            }
        }
        return false;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_CODE_CHECK_SETTING){
            finish();
            final String[] p = permissions;

            RealRxPermission.getInstance(getApplication()).onRequestPermissionsResult(permissions);
        }
    }

    @Override
    public void finish() {
        super.finish();
        // Reset the animation to avoid flickering.
        overridePendingTransition(0, 0);
    }

    @Override
    protected void onSaveInstanceState(final Bundle outState) {
        outState.putBooleanArray(SAVE_RATIONALE, shouldShowRequestPermissionRationale);
        super.onSaveInstanceState(outState);
    }

    public void startRequestPermissions(){
        requestPermissions(permissions, REQUEST_CODE);

        for (String permission:permissions) {
            PermissionSharedPref.getInstance(this).increaseCount(permission);
        }
    }

    private boolean[] rationales(@NonNull final String[] permissions) {
        final boolean[] rationales = new boolean[permissions.length];

        for (int i = 0; i < permissions.length; i++) {
            rationales[i] = shouldShowRequestPermissionRationale(permissions[i]);
        }

        return rationales;
    }

    private void showDialogFragment(DialogFragment dialogFragment) {
        hideDialogFragment();

        FragmentManager fragmentManager = getSupportFragmentManager();

        if (fragmentManager != null) {
            try {
                dialogFragment.show(fragmentManager, "dialog");
                dialogFragment.setCancelable(false);
            } catch (IllegalStateException e) {
                // 偶现异常
            }
        }
    }

    private void hideDialogFragment() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        if (fragmentManager != null) {
            Fragment pre = fragmentManager.findFragmentByTag("dialog");
            if (pre instanceof DialogFragment) {
                ((DialogFragment) pre).dismiss();
            }
        }
    }

    private Map<String,Integer> permission_request_image = new HashMap<>();
    {
        permission_request_image.put(Manifest.permission.RECORD_AUDIO, R.drawable.permission_ic_audio);
        permission_request_image.put(Manifest.permission.CAMERA, R.drawable.permission_ic_camera);
        permission_request_image.put(Manifest.permission.READ_CONTACTS, R.drawable.permission_ic_contact);
        permission_request_image.put(Manifest.permission.WRITE_CONTACTS, R.drawable.permission_ic_contact);
        permission_request_image.put(Manifest.permission.ACCESS_COARSE_LOCATION, R.drawable.permission_ic_location);
        permission_request_image.put(Manifest.permission.ACCESS_FINE_LOCATION, R.drawable.permission_ic_location);
        permission_request_image.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, R.drawable.permission_ic_storage);
        permission_request_image.put(Manifest.permission.READ_EXTERNAL_STORAGE, R.drawable.permission_ic_storage);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            permission_request_image.put(Manifest.permission.READ_MEDIA_AUDIO, R.drawable.permission_ic_storage);
            permission_request_image.put(Manifest.permission.READ_MEDIA_IMAGES, R.drawable.permission_ic_storage);
            permission_request_image.put(Manifest.permission.READ_MEDIA_VIDEO, R.drawable.permission_ic_storage);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
                permission_request_image.put(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED, R.drawable.permission_ic_storage);
            }
        }
        permission_request_image.put(Manifest.permission.READ_PHONE_STATE, R.drawable.permission_ic_phone);

        permission_request_image.put(Manifest.permission.CAMERA + "&&" + Manifest.permission.RECORD_AUDIO, R.drawable.permission_ic_audio_camera);
        permission_request_image.put(Manifest.permission.CAMERA + "&&" + Manifest.permission.READ_EXTERNAL_STORAGE, R.drawable.permission_ic_file_camera);
        permission_request_image.put(Manifest.permission.CAMERA + "&&" + Manifest.permission.WRITE_EXTERNAL_STORAGE, R.drawable.permission_ic_file_camera);

        permission_request_image.put(Manifest.permission.READ_CONTACTS + "&&" + Manifest.permission.READ_EXTERNAL_STORAGE, R.drawable.permission_ic_storage_contact);
        permission_request_image.put(Manifest.permission.READ_CONTACTS + "&&" + Manifest.permission.WRITE_EXTERNAL_STORAGE, R.drawable.permission_ic_storage_contact);
        permission_request_image.put(Manifest.permission.WRITE_CONTACTS + "&&" + Manifest.permission.WRITE_EXTERNAL_STORAGE, R.drawable.permission_ic_storage_contact);
        permission_request_image.put(Manifest.permission.READ_EXTERNAL_STORAGE + "&&" + Manifest.permission.WRITE_CONTACTS, R.drawable.permission_ic_storage_contact);

        permission_request_image.put(Manifest.permission.READ_EXTERNAL_STORAGE + "&&" + Manifest.permission.RECORD_AUDIO, R.drawable.permission_ic_audio_storage);
        permission_request_image.put(Manifest.permission.RECORD_AUDIO + "&&" + Manifest.permission.WRITE_EXTERNAL_STORAGE, R.drawable.permission_ic_audio_storage);
        permission_request_image.put(Manifest.permission.ACTIVITY_RECOGNITION, R.drawable.permission_ic_steps);
    }

    private int getPermissionIcon(String[] permissions){

        if (permissions == null || permissions.length==0){
            return R.drawable.permission_ic_phone;
        }else if (permissions.length == 1){
            Integer drawableId = permission_request_image.get(permissions[0]);
            if (drawableId!=null) return drawableId;
        } else {

            Arrays.sort(permissions);

            String key = permissions[0]+"&&"+permissions[1];
            Integer drawableId = permission_request_image.get(key);
            if (drawableId==null){
                drawableId = permission_request_image.get(permissions[0]);
            }
            if (drawableId!=null) return drawableId;
        }


        return R.drawable.permission_ic_phone;
    }

    public void notNow() {
        finish();
        RealRxPermission.getInstance(getApplication()).onRequestPermissionsResult(permissions);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

    }


    private void setWindowFlag() {
//		getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
    }
}
